package com.handinglian.system.service.impl;

import com.handinglian.common.exception.BizException;
import com.handinglian.common.utils.FastJsonUtil;
import com.handinglian.common.utils.GeneralUtil;
import com.handinglian.common.utils.StringUtil;
import com.handinglian.system.dto.MenuPermissionDto;
import com.handinglian.system.dto.PermissionDto;
import com.handinglian.system.dto.RoleDto;
import com.handinglian.system.entity.Role;
import com.handinglian.system.entity.RolePermissionRelation;
import com.handinglian.system.entity.UserRoleRelation;
import com.handinglian.system.mapper.RoleMapper;
import com.handinglian.system.param.RoleCreateParam;
import com.handinglian.system.param.RoleUpdateParam;
import com.handinglian.system.service.PermissionService;
import com.handinglian.system.service.RolePermissionRelationService;
import com.handinglian.system.service.RoleService;
import com.handinglian.system.service.UserRoleRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service("roleService")
public class RoleServiceImpl implements RoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private RolePermissionRelationService rolePermissionRelationService;
    @Autowired
    private UserRoleRelationService userRoleRelationService;
    
    @Override
    @Transactional
    public int createRole(RoleCreateParam roleCreateParam) {
        Date now = new Date();
        Role role = FastJsonUtil.ObjectToObject(roleCreateParam, Role.class);
        role.setCreateTime(now);
        role.setUpdateTime(now);
        int amount = roleMapper.insertSelective(role);

        String permissionIdStr = roleCreateParam.getPermissionIds();
        String[] permissionIds = StringUtil.isBlank(permissionIdStr) ? new String[]{} : permissionIdStr.split(",");
        List<RolePermissionRelation> rolePermissionRelations = new ArrayList<>();
        //创建角色权限联系
        for (String permissionId : permissionIds){
            RolePermissionRelation rolePermissionRelation = new RolePermissionRelation();
            rolePermissionRelation.setRoleId(role.getRoleId());
            rolePermissionRelation.setPermissionId(Integer.valueOf(permissionId));
            rolePermissionRelations.add(rolePermissionRelation);
        }
        rolePermissionRelationService.createRolePermissionBatch(rolePermissionRelations);
        return amount;
    }
    @Override
    @Transactional
    public int updateRole(RoleUpdateParam roleUpdateParam) {
        Role role = FastJsonUtil.ObjectToObject(roleUpdateParam, Role.class);
        role.setUpdateTime(new Date());
        int amount = roleMapper.updateByPrimaryKeySelective(role);

        String permissionIdStr = roleUpdateParam.getPermissionIds();
        String[] permissionIds = StringUtil.isBlank(permissionIdStr) ? new String[]{} : permissionIdStr.split(",");
        List<String> permissionList = new ArrayList<String>(Arrays.asList(permissionIds));

        List<Integer> parmaPermissionList = permissionList.stream().map(permissionId -> Integer.valueOf(permissionId)).collect(Collectors.toList());
        List<Integer> dbPermissionIdList = rolePermissionRelationService.inquirePermissionIdByRoleId(roleUpdateParam.getRoleId());

        //获取需要添加和删除的permissionId集合
        List<Integer> addList = GeneralUtil.getAddList(parmaPermissionList, dbPermissionIdList);
        List<Integer> missingList = GeneralUtil.getMissingList(parmaPermissionList, dbPermissionIdList);

        //批量添加角色权限关联
        List<RolePermissionRelation> addRolePermissionRelations = new ArrayList<>();
        for (Integer permissionId : addList){
            RolePermissionRelation rolePermissionRelation = new RolePermissionRelation();
            rolePermissionRelation.setRoleId(roleUpdateParam.getRoleId());
            rolePermissionRelation.setPermissionId(permissionId);
            addRolePermissionRelations.add(rolePermissionRelation);
        }
        if (addRolePermissionRelations.size() > 0){
            rolePermissionRelationService.createRolePermissionBatch(addRolePermissionRelations);
        }

        //批量删除角色权限关联
        if (missingList.size() > 0){
            rolePermissionRelationService.deleteByRoleIdAndPermissionIdIn(roleUpdateParam.getRoleId(), missingList);
        }
        return amount;
    }

    @Override
    @Transactional
    public int deleteRole(Integer roleId) {
        List<UserRoleRelation> userRoleRelations = userRoleRelationService.inquireUserRoleRelationByRoleId(roleId);
        if (userRoleRelations.size() > 0){
            throw BizException.ROLE_USED;
        }

        rolePermissionRelationService.deleteByRoleId(roleId);
        return roleMapper.deleteByPrimaryKey(roleId);
    }

    @Override
    public RoleDto loadRole(Integer roleId) {
        Role role = roleMapper.selectByPrimaryKey(roleId);
        return FastJsonUtil.ObjectToObject(role, RoleDto.class);
    }

    @Override
    public List<RoleDto> inquireRoleList() {
        List<Role> roles = roleMapper.find();
        return FastJsonUtil.ListToList(roles, RoleDto.class);
    }

    @Override
    public RoleDto inquireRolePermissionList(Integer roleId) {
        List<PermissionDto> permissionDtos = permissionService.inquirePermissionByRoleId(roleId);
        RoleDto roleDto = loadRole(roleId);
        roleDto.setPermissions(permissionDtos);
        return roleDto;
    }


    @Override
    public List<MenuPermissionDto> getRoleMenuPermissionList(Integer roleId) {
        return roleMapper.getRoleMenuPermissionList(roleId);
    }

    @Override
    public Role getByUserId(Integer userId) {
        return roleMapper.findOneByUserId(userId);
    }
}
